package com.zhiche.lisa.core.utils.qiniu.util;

import com.google.gson.Gson;
import com.mysql.jdbc.StringUtils;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.zhiche.lisa.core.utils.qiniu.config.QiniuConfig;
import com.zhiche.lisa.core.utils.qiniu.domain.QuniuResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.UnsupportedEncodingException;


/**
 * 七牛工具类
 * https://developer.qiniu.com/kodo/sdk/1239/java
 */
@Component
public class QiniuUtils {

    private static QiniuConfig qiniuConfig;

    @Autowired
    public void setQiniuConfig(QiniuConfig qiniuConfig) {
        QiniuUtils.qiniuConfig = qiniuConfig;
    }

    private static Auth getAuth() {
        Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
        return auth;
    }

    /**
     * 得到文件信息
     *
     * @param key
     * @return
     */
    public static FileInfo getFileInfo(String key) {
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        FileInfo fileInfo = null;
        Auth auth = getAuth();
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            fileInfo = bucketManager.stat(qiniuConfig.getBucket(), key);
        } catch (QiniuException ex) {
            System.err.println(ex.response.toString());
        }
        return fileInfo;
    }

    /**
     * 获取文件 hash
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static String getHash(String key) throws Exception {
        FileInfo fileInfo = getFileInfo(key);
        return fileInfo.hash;
    }

    /**
     * 获取文件大小
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static Long getSize(String key) throws Exception {
        FileInfo fileInfo = getFileInfo(key);
        return fileInfo.fsize;
    }

    /**
     * 获取文件类型
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static String getType(String key) throws Exception {
        FileInfo fileInfo = getFileInfo(key);
        return fileInfo.mimeType;
    }

    /**
     * 获取上传时间
     *
     * @param key
     * @return
     */
    public static Long getPutTime(String key) throws Exception {
        FileInfo fileInfo = getFileInfo(key);
        return fileInfo.putTime;
    }

    /**
     * 获取下载凭证
     *
     * @param downloadAddress
     * @param key
     * @return
     */
    public static String generateDownloadTicket(String downloadAddress, String key) {
        if (StringUtils.isNullOrEmpty(key)) {
            return "";
        }
        int invalidationTime = qiniuConfig.getInvalidationTime();
        Auth auth = getAuth();
        String url = downloadAddress;
        return auth.privateDownloadUrl(url + "/" + key, invalidationTime);
    }

    /**
     * 获取下载凭证
     *
     * @param downloadAddress
     * @param key
     * @param treatMethod
     * @return
     */
    public static String generateDownloadTicket(String downloadAddress, String key, String treatMethod) {
        if (StringUtils.isNullOrEmpty(key)) {
            return "";
        }
        int invalidationTime = qiniuConfig.getInvalidationTime();
        Auth auth = getAuth();
        if (!org.apache.commons.lang3.StringUtils.isEmpty(treatMethod)) {
            treatMethod = "?imageView2/" + treatMethod;
        }
        return auth.privateDownloadUrl(downloadAddress + "/" + key + treatMethod, invalidationTime);
    }

    /**
     * 获取图像处理后的下载凭证
     * https://developer.qiniu.com/dora/manual/3683/img-directions-for-use
     * https://developer.qiniu.com/dora/manual/1279/basic-processing-images-imageview2
     *
     * @param key
     * @param treatMethod
     * @param w
     * @param h
     * @return
     */
    public static String generateDownloadTicket(String downloadAddress, String key, String treatMethod, String w, String h) {
        if (StringUtils.isNullOrEmpty(key)) {
            return "";
        }
        int invalidationTime = qiniuConfig.getInvalidationTime();
        Auth auth = getAuth();
        if (!StringUtils.isNullOrEmpty(treatMethod)) {
            if (!StringUtils.isNullOrEmpty(w)) {
                treatMethod = treatMethod + "/w/" + w;
            }
            if (!StringUtils.isNullOrEmpty(h)) {
                treatMethod = treatMethod + "/h/" + h;
            }
            if (!StringUtils.isNullOrEmpty(treatMethod)) {
                treatMethod = "?imageView2/" + treatMethod;
            }
        }
        String url = downloadAddress;
        return auth.privateDownloadUrl(url + "/" + key + treatMethod, invalidationTime);
    }

    /**
     * 根据Bucket获取上传凭证key
     *
     * @return 返回凭证key
     */
    public static String generateSimpleUploadTicket(String bucket) {
        Auth auth = getAuth();
        int invalidationTime = qiniuConfig.getInvalidationTime();
        return auth.uploadToken(bucket, null, invalidationTime, null);
    }

    /**
     * 根据Bucket获取上传凭证key
     *
     * @param bucket
     * @param key
     * @return
     */
    public static String generateSimpleUploadTicket(String bucket, String key) {
        Auth auth = getAuth();
        int invalidationTime = qiniuConfig.getInvalidationTime();
        return auth.uploadToken(bucket, key, invalidationTime, null);
    }


    /**
     * 删除空间中的文件
     *
     * @param key
     * @return
     * @throws QiniuException
     */
    public static Response DeleteFile(String key) throws QiniuException {
        Response response = null;
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        Auth auth = getAuth();
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            response = bucketManager.delete(qiniuConfig.getBucket(), key);
        } catch (QiniuException ex) {
            throw ex;
        }
        return response;
    }

    /**
     * 根据区域名称得到区域
     *
     * @param zoneName
     * @return
     */
    private static Zone getZoneByName(String zoneName) {
        if (zoneName.equals("华北")) {
            return Zone.huabei();
        } else if (zoneName.equals("华南")) {
            return Zone.huanan();
        } else if (zoneName.equals("华东")) {
            return Zone.huadong();
        } else {
            return Zone.autoZone();
        }
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @return
     * @throws QiniuException
     */
    public static QuniuResponse uploadFile(File file) throws QiniuException {
        QuniuResponse quniuResponse = null;
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        UploadManager uploadManager = new UploadManager(cfg);
        String key = null;
        try {
            Response response = uploadManager.put(file, key, generateSimpleUploadTicket(qiniuConfig.getBucket()));
            ;
            quniuResponse = response.jsonToObject(QuniuResponse.class);
        } catch (QiniuException ex) {
            throw ex;
        }
        return quniuResponse;
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @return
     * @throws QiniuException
     */
    public static QuniuResponse uploadFile(File file, String key) throws QiniuException {
        QuniuResponse quniuResponse = null;
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        UploadManager uploadManager = new UploadManager(cfg);
        try {
            Response response = uploadManager.put(file, key, generateSimpleUploadTicket(qiniuConfig.getBucket()));
            ;
            quniuResponse = response.jsonToObject(QuniuResponse.class);
        } catch (QiniuException ex) {
            throw ex;
        }
        return quniuResponse;
    }

    /**
     * 上传文件
     *
     * @param uploadStr 字符串
     * @return
     * @throws QiniuException
     */
    public static DefaultPutRet uploadString(String uploadStr) throws QiniuException {
        Response response = null;

        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        UploadManager uploadManager = new UploadManager(cfg);
        String key = null;
        try {
            byte[] uploadBytes = uploadStr.getBytes("utf-8");
            response = uploadManager.put(uploadBytes, key, generateSimpleUploadTicket(qiniuConfig.getBucket()));
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
            return putRet;

        } catch (QiniuException ex) {
            throw ex;
        } catch (UnsupportedEncodingException ex) {
            //ignore
        }
        return null;
    }

    /**
     * 上传文件
     *
     * @param uploadStr 字符串
     * @return
     * @throws QiniuException
     */
    public static DefaultPutRet uploadString(String uploadStr, String fileName) throws QiniuException {
        Response response = null;

        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZoneByName(qiniuConfig.getZoneName()));
        UploadManager uploadManager = new UploadManager(cfg);
        try {
            byte[] uploadBytes = uploadStr.getBytes("utf-8");
            response = uploadManager.put(uploadBytes, fileName, generateSimpleUploadTicket(qiniuConfig.getBucket()));
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
            return putRet;

        } catch (QiniuException ex) {
            throw ex;
        } catch (UnsupportedEncodingException ex) {
            //ignore
        }
        return null;
    }

    public static String getDownloadUrl(String key) {
        String downloadUrl = QiniuUtils.generateDownloadTicket(qiniuConfig.getDownloadUrl(), key);
        return downloadUrl;
    }
}
